package course.java.simulation.bankandexcute;

import com.alibaba.fastjson.JSON;
import course.java.simulation.common.OperationType;
import course.java.simulation.common.TransactionCommands;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.NoSuchElementException;

/**
 * 交易线程实现
 */
@Slf4j
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TradingExecute implements Runnable {
    private Bank bank;
    private RequestObject requestObject;

    @Override
    public void run() {
        try{
            long threadId = Thread.currentThread().getId();
            String name = Thread.currentThread().getName();
            TransactionCommands transactionCommands = bank.openTransaction(requestObject.getUserId()).get();
            //判断状态是commit还是abort
            boolean executeResult = false;
            if (requestObject.getOperationType() == OperationType.Withdraw) {
                executeResult = transactionCommands.withdrawMoney(requestObject.getAmount());
            } else if (requestObject.getOperationType() == OperationType.Pay) {
                transactionCommands.payMoneyToAccount(requestObject.getAmount());
            } else {
                log.info("未执行具体操作，打印参数:{}",JSON.toJSONString(requestObject));
                log.info("线程相关参数:{}{}",threadId,name);
            }
            if (executeResult) {
                transactionCommands.commit();
                log.info("完成commit操作：{}",JSON.toJSONString(requestObject));
            } else {
                transactionCommands.abort();
                log.info("发生中断：{}",JSON.toJSONString(requestObject));
            }
            double tentativeTotalAmount = transactionCommands.getTentativeTotalAmount();
            log.info("执行完毕，打印执行参数:{}{}{}{}{}{}{}{}", JSON.toJSONString(requestObject),"线程相关信息：{}{}", threadId, name
                    ,"方法执行结果：{}",executeResult ? "success" : "failed", "最终结果",tentativeTotalAmount);
        } catch (NoSuchElementException e) {
            log.error("执行过程中异常，打印异常参数:{}", JSON.toJSONString(requestObject));
        }

    }
}
